package
{
	import exampleSupport.MarkerOutliner;
	
	import org.libspark.flartoolkit.core.FLARCode;
	import org.libspark.flartoolkit.core.param.FLARParam;
	import org.libspark.flartoolkit.core.raster.rgb.FLARRgbRaster_BitmapData;
	import org.libspark.flartoolkit.core.transmat.FLARTransMatResult;
	import org.libspark.flartoolkit.core.types.FLARDoublePoint2d;
	import org.libspark.flartoolkit.detector.FLARSingleMarkerDetector;
	import org.libspark.flartoolkit.pv3d.FLARBaseNode;
	
	public class PaletaJuan implements Detector
	{
		[Embed(source="../lib/camera_para.dat", mimeType="application/octet-stream")]
		private var CameraParameters:Class;
		
		[Embed(source="../lib/square.pat", mimeType="application/octet-stream")]
		private var MarkerPattern:Class;
		
		private var cameraParameters:FLARParam;
		private var markerPattern:FLARCode;
		private var raster:FLARRgbRaster_BitmapData;
		private var detector:FLARSingleMarkerDetector;
		
		private var mainContainer:FLARBaseNode;
		
		private var cam:Camera;
		private var vid:Video;
		private var capture:BitmapData;
		
		private static const RECTANGLE_WIDTH:Number = 1;
		private static const RECTANGLE_HEIGHT:Number = 100;

		public var ballX:Number = 0;
		public var ballY:Number = 0;
		public var velX:Number = 10;
		public var velY:Number = 6;
		private static const BALL_RADIUS:Number = 15;
		public var x_boundarie:Number = 0;
		public var y_boundarie:Number = 0;
		
		public function PaletaJuan()
		{
			/*
			 * cameraParameters will hold our parameters from the camera noted above.
			 * Flar will use the camera parameters to make your 3d stuff
			 * look right
			 */
			this.cameraParameters = new FLARParam();
			this.cameraParameters.loadARParam(new CameraParameters() as ByteArray);
			
			/*
			 * markerPattern will hold the data from our pattern file for Flar
			 * to use to look for our Marker
			 */
			this.markerPattern = new FLARCode(16, 16);
			this.markerPattern.loadARPatt(new MarkerPattern());
			
				//Get our webcam going
			this.cam = Camera.getCamera();
			//Set the webcam to run as 640x480
			//at 30 frames per second
			this.cam.setMode(640, 480, 40);
						
			//Create a new video object to show our webcam
			this.vid = new Video();
			this.vid.width = 640;
			this.vid.height = 480;
			this.vid.x = 0;
			this.vid.y = 0;
			this.vid.attachCamera(cam);
			this.vid.visible = true;
			addChild(this.vid);
			
			/*
			 * capture will hold BitmapData of what is shown on the 
			 * webcam FlarToolkit will use this bitmapdata to look
			 * for our mark pattern
			 * 
			 * we will need to redraw vid to capture every frame
			 */
			this.capture = new BitmapData(vid.width, vid.height, true, 0x0);
			this.capture.draw(vid);
			
			/*
			 * raster will hold our BitmapData for Flar to use
			 */
			raster = new FLARRgbRaster_BitmapData(capture);
			detector = new FLARSingleMarkerDetector(cameraParameters, markerPattern, 80);
			
			// MarkerOutliner is a simple class that draws an outline
			// around the edge of detected markers.
			this.markerOutliner = new MarkerOutliner();
			this.markerOutliner.mouseChildren = false;
			this.addChild(this.markerOutliner);
			
			/*
			 * This is our mainContainer what will happen
			 * is that Flar will give us a transformation
			 * matrix based on the marker and we can use
			 * that transformation matrix to rotate the
			 * mainContainer
			 */
			mainContainer = new FLARBaseNode();

			/*
			 * This is a Transformation matrix which Flar will
			 * fill and then we will use this to rotate mainContainer
			 */
			trans = new FLARTransMatResult();
			
			//Main loop where all the magic happens
			this.addEventListener(Event.ENTER_FRAME, mainEnter);
			
		}

		public function detect():void
		{
			/*
			* Draw the current video screen to our capture
			* Flar will use this to figure out where our marker is
			*/
			this.capture.draw(vid);
			
			if (this.detector.detectMarkerLite(raster, 80) && this.detector.getConfidence() > 0.4){
				//Get the transfomration matrix for the current marker position
				this.detector.getTransformMatrix(trans);
							
				var y1:Number = this.getY();
			
				/* We create the Paddle */
				var rectangle:Rectangle = new Rectangle();
				rectangle.height = RECTANGLE_HEIGHT;
				rectangle.width = RECTANGLE_WIDTH;
				rectangle.x = 100;
				rectangle.y = y1;
				
				/* We Insert the Paddle into the Game */
				var auxi:FLARDoublePoint2d = new FLARDoublePoint2d(rectangle.x,rectangle.y);
				this.markerOutliner.drawRectangle(auxi,RECTANGLE_WIDTH,RECTANGLE_HEIGHT);
				
				var text:TextField = new TextField();
				text.x = 0;
				text.y = 0;
				text.width = 250;
				text.background = true;
				text.selectable = false;
				text.text = "Y = " + GetY(detector) + "\nPosicion Y Cuad :" + rectangle.y;
				addChild(text);
				
				
				/* We update the speed and position of the ball based on simple game
				*  physics
				*/
				ballX += velX;
				ballY += velY;
				if((ballX > this.vid.width - x_boundarie) || (ballX <= 0)) {
					velX = -velX;
				}
				if( (ballY > this.vid.height - y_boundarie) || (ballY <= 0) ) {
					velY = -velY;
				}	
				
				/* We draw the ball and a wrapping rectangle */
				this.markerOutliner.drawBall(ballX,ballY,BALL_RADIUS);
				
				var BallWrapper:Rectangle = new Rectangle();
				
				BallWrapper.x = ballX - BALL_RADIUS;
				BallWrapper.y = ballY - BALL_RADIUS;
				
				BallWrapper.width = BallWrapper.height = 2 * BALL_RADIUS;
				
				if(rectangle.intersects(BallWrapper)){
					velX = -velX;
					velY = velY;	
				}
				//Translates and rotates the mainContainer so it looks right
				//mainContainer.setTransformMatrix(trans);
			}
		}
		
		public function getX():Number
		{
			return new Number(((this.detector.getSquare().sqvertex[0].x + this.detector.getSquare().sqvertex[1].x
							+ this.detector.getSquare().sqvertex[2].x + this.detector.getSquare().sqvertex[3].x)/4));
		}
		
		public function getY():Number
		{
			return new Number(((this.detector.getSquare().sqvertex[0].y + this.detector.getSquare().sqvertex[1].y
							+ this.detector.getSquare().sqvertex[2].y + this.detector.getSquare().sqvertex[3].y)/4));
		}
		
	}
}